import { VxeGlobalRendererHandles } from 'vxe-table'
import XEUtils from 'xe-utils'

import { isObject, isFunction } from '@/utils'

export type RenderTableCellOptions = VxeGlobalRendererHandles.RenderTableCellOptions
export type RenderTableCellParams = VxeGlobalRendererHandles.RenderTableCellParams
export type ComponentParams = [RenderTableCellParams, ...any]

/** 事件添加额外参数的方法 */
export function addExtraParams(cellData, originalEvents) {
  if (!originalEvents) return {}
  // 创建一个新的空对象，用于存放带有额外参数的事件
  const eventsWithParams = {}
  // 遍历原始事件对象
  for (const [eventName, eventHandler] of Object.entries(originalEvents)) {
    // 如果原始事件处理程序是一个函数，则使用箭头函数包装，添加额外参数
    if (typeof eventHandler === 'function') {
      eventsWithParams[eventName] = (event, ...args) => {
        // 调用原始事件处理程序，并传入事件、插槽参数和额外参数
        eventHandler(cellData, event, ...args)
      }
    }
  }
  // 返回带有额外参数的事件对象
  return eventsWithParams
}

/** 获取组件的 props */
export function getComponentProps(
  renderOpts: RenderTableCellOptions,
  defaultProps?: { [key: string]: any },
  omitKeys?: string[]
) {
  return XEUtils.omit(Object.assign(defaultProps || {}, renderOpts['props']), omitKeys || [])
}

/** 获取组件的事件 */
export function getComponentEvents(
  renderOpts: RenderTableCellOptions,
  params: RenderTableCellParams,
  omitEventsKeys?: string[]
) {
  return XEUtils.omit(
    addOnPrefix(addExtraParams(params, renderOpts['events'])),
    omitEventsKeys || []
  )
}

/** 获取组件的插槽 */
export function getComponentSlots(renderOpts: RenderTableCellOptions) {
  return renderOpts['props']?.slots
}

/** 创建默认事件处理 */
export function createDefaultEvent(
  renderOpts: RenderTableCellOptions,
  params: RenderTableCellParams,
  eventName: string,
  defaultEvent: (renderOpts: RenderTableCellOptions, componentParams: ComponentParams) => void
) {
  return (...args) => {
    const originalEvents = renderOpts['events']?.[eventName]
    const componentParams: ComponentParams = [params, ...args]
    if (isFunction(originalEvents)) {
      // @ts-ignore 官方类型有误
      originalEvents(...componentParams)
    }
    defaultEvent(renderOpts, componentParams)
  }
}

/** 转换事件对象，将事件名的首字母大写，并添加 on 前缀 */
export function addOnPrefix(eventsObj) {
  const newObj = {}
  if (!isObject(eventsObj)) return newObj
  Object.keys(eventsObj).forEach((key) => {
    const camelCaseKey = `on${key.charAt(0).toUpperCase()}${key.slice(1)}`
    newObj[camelCaseKey] = eventsObj[key]
  })
  return newObj
}
